/**
 * Created by ${PRODUCT_NAME}.
 * User: skylerparr
 * Date: 12/18/10
 * Time: 1:10 PM
 * To change this template use File | Settings | File Templates.
 */
package com.thoughtorigin.relay {
import com.thoughtorigin.service.Message;

import flash.events.Event;

import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertTrue;
import org.flexunit.async.Async;
import org.mockito.integrations.given;
import org.mockito.integrations.mock;

[RunWith("org.mockito.integrations.flexunit4.MockitoClassRunner")]
[Mock(type="com.thoughtorigin.service.Message")]
public class ServiceMessageRelayTest {

    private var _relay: ServiceMessageRelay;
    private var _locator: MockLocator;

    [Before]
    public function setUp(): void {
        _relay = new ServiceMessageRelay();
        _locator = new MockLocator();
        _relay.serviceLocator = _locator;
    }

    [After]
    public function tearDown(): void {
        _relay = null;
        _locator = null;
    }

    [Test]
    public function shouldRelayMessagesToTheCorrectService(): void {
        var service: SampleService = new SampleService();
        var message: Message = mock(Message);
        message.directCallback = function():void{};
        _locator._service = service;
        given(message.serviceName).willReturn("sampleService");
        _relay.relayMessage(message);
        assertTrue(service.serviceHandoff);
    }

    [Test(async)]
    public function shouldRelayMessageToTheCorrectServiceAndListenForReponseEvent(): void {
        var service: SampleService = new SampleService();
        var message: Message = mock(Message);
        message.directCallback = function():void{};
        _locator._service = service;
        given(message.serviceName).willReturn("sampleService");

        var asyncHandler: Function = Async.asyncHandler(this, function(e: Event, obj1: Object): void {
            assertNotNull(e);
        }, 300);

        _relay.addEventListener(Event.COMPLETE, asyncHandler);
        _relay.relayMessage(message);
    }

    [Test(async)]
    public function shouldCallDirectCallbackIfItIsNotNull(): void {
        var service: SampleService = new SampleService();
        var message: Message = mock(Message);
        message.directCallback = function():void{};
        _locator._service = service;
        given(message.serviceName).willReturn("sampleService");

        var asyncHandler: Function = Async.asyncHandler(this, function(e: Event, obj1: Object): void {
            assertNotNull(e);
        }, 300);
        given(message.directCallback).willReturn(asyncHandler);

        _relay.relayMessage(message);
    }
}
}

import com.thoughtorigin.relay.ResponseEvent;
import com.thoughtorigin.service.Message;
import com.thoughtorigin.service.Service;
import com.thoughtorigin.service.ServiceLocator;

import flash.events.Event;
import flash.events.EventDispatcher;

class SampleService extends EventDispatcher implements Service {

    public var serviceHandoff: Boolean = false;

    public function handoff(message:Message):void {
        serviceHandoff = true;
        dispatchEvent(new ResponseEvent(ResponseEvent.RESPONSE, new Event(Event.COMPLETE)));
    }

    public function get serviceName():String {
        return "sampleService";
    }


    public function get createNew():Boolean {
        return false;
    }
}

class MockLocator implements ServiceLocator {

    public var _service: Service;

    public function addService(service:Service):void {
    }

    public function locateService(serviceName:String, callback:Function):void {
        callback.call(this, _service);
    }

    public function removeService(service:Service):void {
    }
}